﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;

namespace QBS.Tools
{
    public class NameValue<TKey, TValue> : Dictionary<TKey, TValue>
    {
        public int Int(TKey key, int def = -1)
        {
            int ret = def;
            int.TryParse(Str(key), out ret);
            return ret;
        }
        public long Long(TKey key, int def = -1)
        {
            long ret = def;
            long.TryParse(Str(key), out ret);
            return ret;
        }
        public string Str(TKey key)
        {
            if (this.Keys.Contains(key))
                return this[key] == null ? "" : this[key].ToStr();
            return "";
        }
    }
    public class ObjectHelper
    {
        public T Clone<T>(T RealObject)
        {
            using (Stream stream = new MemoryStream())
            {
                IFormatter formatter = new BinaryFormatter();
                formatter.Serialize(stream, RealObject);
                stream.Seek(0L, SeekOrigin.Begin);
                return (T)formatter.Deserialize(stream);
            }
        }

        public static List<T2> Copy<T1, T2>(List<T1> source)
            where T1 : class
            where T2 : class
        {
            List<T2> result = new List<T2>();
            if ((source != null) && (source.Count >= 1))
            {
                source.ForEach(delegate(T1 o)
                {
                    try
                    {
                        T2 item = Copy<T1, T2>(o);
                        result.Add(item);
                    }
                    catch
                    {
                    }
                });
            }
            return result;
        }

        public static T2 Copy<T1, T2>(T1 source)
            where T1 : class
            where T2 : class
        {
            if (source == null)
            {
                return default(T2);
            }
            T2 local = (T2)Activator.CreateInstance(typeof(T2));
            PropertyInfo[] properties = local.GetType().GetProperties();
            PropertyInfo[] infoArray2 = source.GetType().GetProperties();
            PropertyInfo[] infoArray3 = properties;
            for (int i = 0; i < infoArray3.Length; i++)
            {
                Func<PropertyInfo, bool> predicate = null;
                PropertyInfo Ptarget = infoArray3[i];
                try
                {
                    if (predicate == null)
                    {
                        predicate = o => Ptarget.Name.Equals(o.Name, StringComparison.CurrentCultureIgnoreCase);
                    }
                    PropertyInfo info = infoArray2.FirstOrDefault<PropertyInfo>(predicate);
                    Ptarget.SetValue(local, info.GetValue(source, info.GetIndexParameters()), null);
                }
                catch
                {
                }
            }
            return local;
        }

        public static IList<Dictionary<string, string>> DataTableToDictionary(DataTable _DataTable)
        {
            List<Dictionary<string, string>> list = new List<Dictionary<string, string>>();
            if ((_DataTable == null) || (_DataTable.Rows.Count < 1))
            {
                return list;
            }
            return _DataTable.Rows.Cast<DataRow>().Select<DataRow, Dictionary<string, string>>(delegate(DataRow x)
            {
                Dictionary<string, string> dictionary = new Dictionary<string, string>();
                foreach (DataColumn column in _DataTable.Columns)
                {
                    dictionary.Add(column.ColumnName, x[column.ColumnName].ToStr());
                }
                return dictionary;
            }).ToList<Dictionary<string, string>>();
        }

        public static T DataRowToIList<T>(DataTable _DataTable) where T : class
        {
            if ((_DataTable != null) && (_DataTable.Rows.Count >= 1))
            {
                Type type = typeof(T);
                DataRow row = _DataTable.Rows[0];

                T local = (T)Activator.CreateInstance(typeof(T));
                foreach (PropertyInfo info in type.GetProperties())
                {
                    if (_DataTable.Columns.Contains(info.Name))
                    {
                        try
                        {
                            info.SetValue(local, Convert.ChangeType(row[info.Name], info.PropertyType), null);
                        }
                        catch
                        {
                            try
                            {
                                string name = info.PropertyType.Name;
                                if ((name != null) && (name == "Guid"))
                                {
                                    info.SetValue(local, Guid.Parse(row[info.Name].ToStr()), null);
                                }
                                else
                                {
                                    info.SetValue(local, row[info.Name], null);
                                }
                            }
                            catch
                            {
                            }
                        }
                    }
                }
                return local;
            }
            return null;
        }
        public static List<T> DataTableToIList<T>(DataTable _DataTable) where T : class
        {
            List<T> list = new List<T>();
            if ((_DataTable != null) && (_DataTable.Rows.Count >= 1))
            {
                Type type = typeof(T);
                foreach (DataRow row in _DataTable.Rows)
                {
                    T local = (T)Activator.CreateInstance(typeof(T));
                    foreach (PropertyInfo info in type.GetProperties())
                    {
                        if (_DataTable.Columns.Contains(info.Name))
                        {
                            try
                            {
                                info.SetValue(local, Convert.ChangeType(row[info.Name], info.PropertyType), null);
                            }
                            catch
                            {
                                try
                                {
                                    string name = info.PropertyType.Name;
                                    if ((name != null) && (name == "Guid"))
                                    {
                                        info.SetValue(local, Guid.Parse(row[info.Name].ToStr()), null);
                                    }
                                    else
                                    {
                                        info.SetValue(local, row[info.Name], null);
                                    }
                                }
                                catch
                                {
                                }
                            }
                        }
                    }
                    list.Add(local);
                }
            }
            return list;
        }

        public static StringBuilder DataTableToJson(DataTable _DataTable, Dictionary<string, string> keys = null)
        {
            StringBuilder builder = new StringBuilder();
            if (((_DataTable == null) || (_DataTable.Rows.Count < 1)) || (_DataTable.Columns.Count < 1))
            {
                return builder.Append("[]");
            }
            if (keys == null)
            {
                keys = new Dictionary<string, string>();
            }
            string[] strArray = new string[_DataTable.Columns.Count - 1];
            string[] strArray2 = new string[_DataTable.Columns.Count - 1];
            int index = 0;
            while (index < strArray.Length)
            {
                strArray[index] = _DataTable.Columns[index].ColumnName;
                if (!(!keys.Keys.Contains<string>(strArray[index]) || string.IsNullOrWhiteSpace(keys[strArray[index]])))
                {
                    strArray2[index] = keys[strArray[index].Trim()];
                }
                else
                {
                    strArray2[index] = strArray[index];
                }
                index++;
            }
            string columnName = _DataTable.Columns[_DataTable.Columns.Count - 1].ColumnName;
            string source = columnName;
            if (!(!keys.Keys.Contains<string>(columnName) || string.IsNullOrWhiteSpace(keys[columnName])))
            {
                source = keys[source];
            }
            builder.Append("[");
            foreach (DataRow row in _DataTable.Rows)
            {
                builder.Append("{");
                for (index = 0; index < strArray.Length; index++)
                {
                    builder.Append("\"").Append(strArray2[index].ToStr().Replace("'", "‘").Replace("\"", "“")).Append("\":\"").Append(row[strArray[index]].ToStr().Replace("'", "‘").Replace("\"", "“")).Append("\",");
                }
                builder.Append("\"").Append(source.ToStr().Replace("'", "‘").Replace("\"", "“")).Append("\":\"").Append(row[columnName].ToStr().Replace("'", "‘").Replace("\"", "“")).Append("\"},");
            }
            builder.Remove(builder.Length - 1, 1);
            builder.Append("]");
            return builder;
        }

    }
}